package com.atguigu.gulimall.member.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.atguigu.gulimall.member.entity.MemberLevelEntity;
import com.atguigu.gulimall.member.exception.PhoneExistException;
import com.atguigu.gulimall.member.exception.UsernameExistException;
import com.atguigu.gulimall.member.service.MemberLevelService;
import com.atguigu.gulimall.member.vo.MemberLoginVo;
import com.atguigu.gulimall.member.vo.MemberRegistVo;
import com.atguigu.gulimall.member.vo.SocialUser;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import org.apache.commons.lang3.StringUtils;
import org.apache.ibatis.javassist.compiler.ast.Member;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.http.ResponseEntity;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Service;
import java.util.Map;
import java.util.UUID;
import java.util.concurrent.TimeUnit;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.atguigu.common.utils.PageUtils;
import com.atguigu.common.utils.Query;

import com.atguigu.gulimall.member.dao.MemberDao;
import com.atguigu.gulimall.member.entity.MemberEntity;
import com.atguigu.gulimall.member.service.MemberService;
import org.springframework.web.client.RestTemplate;


@Service("memberService")
public class MemberServiceImpl extends ServiceImpl<MemberDao, MemberEntity> implements MemberService {
    @Autowired
    private MemberLevelService memberLevelService;
    @Autowired
    private StringRedisTemplate redisTemplate;
    @Autowired
    private RestTemplate restTemplate;
    @Override
    public PageUtils queryPage(Map<String, Object> params) {
        IPage<MemberEntity> page = this.page(
                new Query<MemberEntity>().getPage(params),
                new QueryWrapper<MemberEntity>()
        );

        return new PageUtils(page);
    }

    @Override
    public void regist(MemberRegistVo vo) {
        System.out.println(vo);
        MemberEntity memberEntity = new MemberEntity();
        MemberLevelEntity one = memberLevelService.getOne(new LambdaQueryWrapper<MemberLevelEntity>().eq(MemberLevelEntity::getDefaultStatus, 1));
        memberEntity.setLevelId(one.getId());
        checkUsernameUnique(vo.getUserName());
        checkPhoneUnique(vo.getPhone());
        memberEntity.setUsername(vo.getUserName());
        memberEntity.setNickname(vo.getUserName());
        memberEntity.setMobile(vo.getPhone());
        BCryptPasswordEncoder bCryptPasswordEncoder = new BCryptPasswordEncoder();
        String encode = bCryptPasswordEncoder.encode(vo.getPassword());
        memberEntity.setPassword(encode);
        this.save(memberEntity);
    }

    @Override
    public void checkPhoneUnique(String phone) throws PhoneExistException{
         if (this.count(new LambdaQueryWrapper<MemberEntity>().eq(MemberEntity::getMobile, phone))!=0){
             throw new PhoneExistException();
         }
    }

    @Override
    public void checkUsernameUnique(String username) throws UsernameExistException{
        if ( this.count(new LambdaQueryWrapper<MemberEntity>().eq(MemberEntity::getUsername, username))!=0){
            throw new UsernameExistException();
        }
    }

    @Override
    public MemberEntity login(MemberLoginVo vo) {
        String loginacct = vo.getLoginacct();
        String password = vo.getPassword();
        BCryptPasswordEncoder bCryptPasswordEncoder = new BCryptPasswordEncoder();
        MemberEntity one = getOne(new LambdaQueryWrapper<MemberEntity>().eq(MemberEntity::getUsername, loginacct).or().eq(MemberEntity::getMobile,loginacct));
        if (one==null){
            return null;
        }else {
            boolean matches = bCryptPasswordEncoder.matches(password, one.getPassword());
            if (matches){
                return one;
            }else {
                return null;
            }
        }
    }

    @Override
    public MemberEntity login(SocialUser socialUser) {
        MemberEntity memberEntity = null;
        JSONObject jsonObject = null;
        System.out.println(socialUser);
        ResponseEntity<String> response = restTemplate.getForEntity("https://gitee.com/api/v5/user?access_token=" + socialUser.getAccess_token(), String.class);
        if (response.getStatusCodeValue()==200){
            String json = response.getBody();
             jsonObject = JSON.parseObject(json);
            String uid = jsonObject.getString("id");
             memberEntity = this.getOne(new LambdaQueryWrapper<MemberEntity>().eq(MemberEntity::getSocialUid, uid));
            redisTemplate.opsForValue().set(uid,socialUser.getAccess_token(),socialUser.getExpires_in(), TimeUnit.SECONDS);
        }else {
            throw new RuntimeException("查询失败");
        }
        if (memberEntity!=null){
            return memberEntity;
        }else {
            memberEntity=new MemberEntity();
            String name = jsonObject.getString("name");
            String login = jsonObject.getString("login");
            String email = jsonObject.getString("email");
            memberEntity.setNickname(name);
            if (StringUtils.isEmpty(email)){
                memberEntity.setEmail(email);
            }
            int count = this.count(new LambdaQueryWrapper<MemberEntity>().eq(MemberEntity::getUsername, login));
            if (count>0){
                String username = login + UUID.randomUUID().toString().replaceAll("[^0-9]", "").substring(0, 4);
                System.out.println("username");
                memberEntity.setUsername(username);
            }else {
                memberEntity.setUsername(login);
            }
            memberEntity.setSocialUid(jsonObject.getString("id"));
            memberEntity.setLevelId(1L);
            save(memberEntity);
            return memberEntity;
        }

    }
}